home *** CD-ROM | disk | FTP | other *** search
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ;
- ; Filename : Irq.asm
- ; Included from: Main Assembley Module
- ; Description : Irq handler for timing/tracking vertical retrace
- ;
- ; Written by: John McCarthy
- ; 1316 Redwood Lane
- ; Pickering, Ontario.
- ; Canada, Earth, Milky Way (for those out-of-towners)
- ; L1X 1C5
- ;
- ; Internet/Usenet: BRIAN.MCCARTHY@CANREM.COM
- ; Fidonet: Brian McCarthy 1:229/15
- ; RIME/Relaynet: ->CRS
- ;
- ; Home phone, (905) 831-1944, don't call at 2 am eh!
- ;
- ; John Mccarthy would really love to work for a company programming Robots
- ; or doing some high intensive CPU work. Hint. Hint.
- ;
- ; Send me your protected mode source code!
- ; Send me your Objects!
- ; But most of all, Send me a postcard!!!!
- ;
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
-
- .386p
- jumps
-
- include pmode.ext
- include macros.inc
-
- public _irq_setpmirq
- public _irq_resetpmirq
- public _irq_resetrastercount
- public _irq_timeraster
- public _irq_set_timer
- public _irq_reset_timer
- public _irq_findcontrol
-
- public _irq_tracespast
- public _irq_framenumber
-
- public _irqcontrol
-
- input_1 equ 03dah ; input status #1 register
-
- pmodeirq equ 0 ; you could also use irq 8
-
- number_of_irq_subroutines equ 8
-
- .386p
- jumps
-
- code32 segment para public use32
- assume cs:code32, ds:code32
-
- _irq_tracespast dd 0 ; contains frame speed (irq driven)
- _irq_framenumber dd 0 ; number of frames total,eg 23400 = 13 mins
- rmirqbuf db 21 dup(?) ; buffer for rm IRQ callback code
- ormirqvect dd 0
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Protected mode IRQ handler
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
-
- pmirq0: ; protected mode IRQ0 handler
- push eax
- mov al,20h
- out 20h,al
- sti
- cld
- push ebx ecx edx esi edi ebp ds
- mov ds, [cs:_seldata]
-
- ; put your protected mode irq code here!!!!!
- ;-------------------------------------------
-
-
-
- ;-------------------------------------------
-
- ; now my code, this is where I inc that variable
- ; protected mode version is easy!
-
- inc _irq_tracespast
- inc _irq_framenumber
-
- i = 0
- rept number_of_irq_subroutines
- call [d _irqcontrol+i*4] ; call selected IRQ subroutines
- i=i+1
- endm
-
- pop ds ebp edi esi edx ecx ebx eax
- iretd
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; _irq_setpmirq: Get protected mode IRQ going
- ; In=Out=Null
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
-
- _irq_setpmirq:
- pushad
- mov ax,900h
- int 31h
- push ax
-
- mov bl,pmodeirq
- mov edx,offset pmirq0
- call _setirqvect
- xor al,al
- call _setirqmask
- mov edi,offset rmirqbuf
- call _rmpmirqset
- mov ormirqvect,eax
-
- call _irq_timeraster
- call _irq_set_timer
-
- pop ax
- int 31h
- popad
- ret
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; _irq_resetpmirq: Unhook protected mode IRQ and reset original timer
- ; In=Out=Null
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
-
- _irq_resetpmirq:
- mov ax, 900h
- int 31h
- push ax
-
- mov bl,pmodeirq
- mov eax,ormirqvect
- call _rmpmirqfree
-
- mov al,1
- call _setirqmask
-
- pop ax
- int 31h
-
- jmp _irq_reset_timer
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Set Irq speed
- ; In:
- ; AX = 1193180/# interrupts per second
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
-
- _irq_set_timer:
- push ax
- mov al,36h
- out 43h,al
- pop ax
- out 40h,al
- mov al,ah
- out 40h,al
-
- ret
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Reset Irq speed to default speed
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
-
- _irq_reset_timer: ; reset timer for exit
- mov al,36h
- out 43h,al
-
- mov ax,0
- out 40h,al
- out 40h,al
- ret
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; _irq_resetrastercount: reset counters (done before anmation loop)
- ; In=Out=Null
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
-
- _irq_resetrastercount: ; reset count before any animation loop
- mov _irq_tracespast,1
- mov _irq_framenumber,0
- ret
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; _irq_timeraster: Guess what this does?
- ; In=Null
- ; Out:
- ; AX=time for raster to occure
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
-
- _irq_timeraster:
- pushad
-
- mov ax, 900h
- int 31h
- push ax
-
- mov dx, input_1 ; input# 1 reg
- loop1:
- in al,dx ; wait for vsync
- test al,8
- jnz loop1
- loop2:
- in al,dx
- test al,8
- jz loop2
-
- mov al,36h ; reset timer
- out 43h,al
- mov al,0
- out 40h,al
- mov al,0
- out 40h,al
- loop3:
- in al,dx ; wait for vsync
- test al,8
- jnz loop3
- loop4:
- in al,dx
- test al,8
- jz loop4
-
- xor al,al ; this calculation code courtesy future_crew
- out 43h,al ; from mental.exe
- in al,40h
- mov ah,al
- in al,40h
- xchg al,ah
- neg ax
- shr ax,1
- movzx eax,ax
- mov [esp+30],ax
-
- pop ax
- int 31h
-
- popad
- ret
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Find next available control vector
- ; Out:
- ; CF - 1 no control availeble
- ; ECX = ?
- ; CF - 0 control available
- ; ECX = next usable jump number. eg _irqcontrol[ecx*4] (0,1,2,3...)
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
-
- _irq_findcontrol:
- push eax edi
- mov ecx,number_of_irq_subroutines
- mov edi,offset _irqcontrol
- mov eax,offset _ret
- repnz scasd
- neg ecx
- sub ecx,-number_of_irq_subroutines+1
- pop edi eax
- ret
-
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; These are the user difinable IRQ controlled jump vectors:
- ;
- ; You can have a certine function performed every vertical retrace just
- ; by setting these to point to the code you wish to be called. When
- ; you want to disable the subroutine, just reset these vectors to offset
- ; _ret.
- ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
-
- _irqcontrol:
- rept number_of_irq_subroutines
- dd offset _ret
- endm
-
- code32 ends
- end